fn walk(path: &Path, is_root: bool) -> CargoResult<u64> {
if !path.is_dir() {
- return Ok(try!(fs::stat(path)).modified)
+ // An fs::stat error here is either because path is a
+ // broken symlink, a permissions error, or a race
+ // condition where this path was rm'ed - either way,
+ // we can ignore the error and treat the path's mtime
+ // as 0.
+ return Ok(fs::stat(path).map(|s| s.modified).unwrap_or(0))
}
// Don't recurse into any sub-packages that we have
if !is_root && path.join("Cargo.toml").exists() { return Ok(0) }
}
}
+#[deriving(PartialEq,Clone)]
+struct SymlinkBuilder {
+ dst: Path,
+ src: Path
+}
+
+impl SymlinkBuilder {
+ pub fn new(dst: Path, src: Path) -> SymlinkBuilder {
+ SymlinkBuilder { dst: dst, src: src }
+ }
+
+ fn mk(&self) -> Result<(), String> {
+ try!(mkdir_recursive(&self.dirname()));
+
+ fs::symlink(&self.dst, &self.src)
+ .with_err_msg(format!("Could not create symlink; dst={} src={}",
+ self.dst.display(), self.src.display()))
+ }
+
+ fn dirname(&self) -> Path {
+ Path::new(self.src.dirname())
+ }
+}
+
#[deriving(PartialEq,Clone)]
pub struct ProjectBuilder {
name: String,
root: Path,
- files: Vec<FileBuilder>
+ files: Vec<FileBuilder>,
+ symlinks: Vec<SymlinkBuilder>
}
impl ProjectBuilder {
ProjectBuilder {
name: name.to_str(),
root: root,
- files: vec!()
+ files: vec!(),
+ symlinks: vec!()
}
}
self
}
+ pub fn symlink<T: BytesContainer>(mut self, dst: T,
+ src: T) -> ProjectBuilder {
+ self.symlinks.push(SymlinkBuilder::new(self.root.join(dst),
+ self.root.join(src)));
+ self
+ }
+
// TODO: return something different than a ProjectBuilder
pub fn build<'a>(&'a self) -> &'a ProjectBuilder {
match self.build_with_result() {
try!(file.mk());
}
+ for symlink in self.symlinks.iter() {
+ try!(symlink.mk());
+ }
+
Ok(())
}
assert_that(p.cargo_process("cargo-build"),
execs().with_status(0));
})
+
+test!(ignore_bogus_symlinks {
+ let p = project("foo")
+ .file("Cargo.toml", basic_bin_manifest("foo").as_slice())
+ .file("src/foo.rs", main_file(r#""i am foo""#, []).as_slice())
+ .symlink("Notafile", "bar");
+
+ assert_that(p.cargo_process("cargo-build"), execs());
+ assert_that(&p.bin("foo"), existing_file());
+
+ assert_that(
+ process(p.bin("foo")),
+ execs().with_stdout("i am foo\n"));
+})